home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / basic / qlib54.zip / DATA.DOC < prev    next >
Text File  |  1992-02-24  |  47KB  |  1,232 lines

  1.  
  2.     DATA routines manipulate numeric or string data.  Single data points
  3.     or portions of arrays may be shifted left or right (equivalent to
  4.     multiplying or dividing by powers of 2), integers may be added to selected
  5.     array elements, or arrays may be multiplied by real-number constants.
  6.     INSTR-like functions find the LAST match of a sub-string in a string, 
  7.     count the number of matches of a sub-string in a string, or remove portions
  8.     of strings.  QLIB Array subroutines are more compact than equivalent
  9.     BASIC FOR ... NEXT loops, and can be as much as 20 times faster.
  10.  
  11.     (Registered version only)
  12.     Many DATA subroutines support huge model arrays.  To use huge arrays,
  13.     start QB with the /ah switch, compile using BC's /ah switch, and link
  14.     with QLIBH.LIB instead of QLIB.LIB.
  15.  
  16.     QLIB DATA routines generally follow these rules:
  17.  
  18.          1) Several subroutines require a math coprocessor (either 8087,
  19.             80287 or 80387, referred to as 80x87).  This requirement is
  20.             clearly stated.  Several subroutines will use the 80x87 if
  21.             available or will use QuickBASIC's (or BC7/QBX's) 8087 emulator.
  22.  
  23.          2) a subroutine with INT, LNG, SNG or DBL in its name is to be
  24.             used with integer, long integer, single-precision real or
  25.             double-precision real number data, respectively.  Subroutines
  26.             with CUR in the name are for BC7/QBX's CURRENCY data type.
  27.  
  28.          3) subroutines using real numbers (SNG or DBL) require data in
  29.             IEEE floating-point format unless otherwise stated.  This is
  30.             the default format for Microsoft's current BASIC and QuickBASIC
  31.             compilers; in most cases this requirement is not a problem.
  32.  
  33.  
  34.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  35.  
  36.     Subroutine: AddINTArray(s%, p%, n%, value%, oops%)
  37.     object code: addintn.obj
  38.  
  39.     Subroutine: AddLNGArray(s%, p%, n%, value%, oops%)
  40.     object code: lngarray.asm
  41.  
  42.     Adds an integer to the first n% elements of an integer or long
  43.     integer array.  You can subtract by adding a negative number.  If the
  44.     addition caused any of the array elements to overflow, oops% indicates
  45.     the number of overflows.
  46.  
  47.     Example:
  48.          DIM Array1%(10000)
  49.           .
  50.           .
  51.          value% = -6: n% = 1000
  52.          s% = VARSEG(Array1%(0))      ' s% = segment where array located
  53.          p% = VARPTR(Array1%(0))      ' p% = offset of array in segment
  54.          CALL AddINTArray(s%, p%, n%, value%, oops%)
  55.          IF oops% THEN PRINT "Uh oh, overflowed somewhere..."
  56.          REM  we just subtracted six from the first 1000 elements of the array
  57.          REM  Array1%().
  58.  
  59.  
  60.  
  61.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  62.  
  63.     Subroutine: AddDBL(a#, b#, c#, oops%)
  64.     object code: adddbl.obj
  65.  
  66.          AddDBL adds two double-precision floating point numbers, returning
  67.     c# as the result and an error flag to warn of overflow, rather than
  68.     crashing the program on overflow.  a# and b# may be positive or
  69.     negative.  Oops% = 0 if no problems, or oops% = -1 if an overflow
  70.     occurred.  If AddDBL overflowed, the previous value of c# will not be
  71.     lost.  AddDBL is up to 3 times faster than BASIC on computers without
  72.     8087.  8087 not required.
  73.  
  74.     Example:
  75.          a# = 123.456789
  76.          b# = -23.456
  77.          CALL = AddDBL(a#, b#, c#, oops%)  ' results: oops% = 0, c# = 100.00789
  78.          IF oops% = -1 THEN                ' check for errors anyway
  79.                .
  80.                .
  81.                .
  82.  
  83.  
  84.  
  85.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  86.  
  87.     Subroutine: AddSNG(a!, b!, c!, oops%)
  88.     object code: addsng.obj
  89.  
  90.          AddSNG adds two single-precision floating point numbers, returning
  91.     c! as the result and an error flag to warn of overflow, rather than
  92.     crashing the program on overflow.  a! and b! may be positive or
  93.     negative.  Oops% = 0 if no problems, or oops% = -1 if an overflow
  94.     occurred.  If AddSNG overflowed, the previous value of c! will not be
  95.     lost.  AddSNG is up to 9 times faster than BASIC on computers without
  96.     8087.
  97.  
  98.     Example:
  99.          a! = 123.456
  100.          b! = -23.456
  101.          CALL = AddSNG(a!, b!, c!, oops%)  ' results in oops% = 0, c! = 100.00
  102.          IF oops% = -1 THEN                ' check for errors anyway
  103.                .
  104.                .
  105.                .
  106.  
  107.  
  108.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  109.  
  110.     Function: segptr% = AllocMem(bytes%)
  111.     object file: allocmem.obj (q$alloc.obj)
  112.  
  113.          AllocMem allocates memory from DOS memory space for QLIB's use.
  114.     Unlike BASIC arrays, memory allocated by AllocMem will not move around,
  115.     so the address of these memory blocks need not be updated before use.
  116.     Use FreeMem(segptr%) to release the memory block for other use.
  117.     This memory space may be used with any QLIB subroutine or function
  118.     which uses VARSEG and VARPTR parameters; segptr% returned by AllocMem
  119.     would be used in place of VARSEG(a(0)) and VARPTR(a(0)) would be
  120.     replaced with an integer variable equal to zero.
  121.  
  122.     Example:
  123.          REM $INCLUDE: 'qlib.bi'
  124.          REM  I want to create a memory space to store 180 short integers
  125.          bytes% = 180: shortseg% = AllocMem(bytes%)
  126.  
  127.          REM  next I'll establish initial values for each short integer
  128.          a% = 0
  129.          FOR i= 0 to 179
  130.          CALL WriteShort(shortseg%, a%, i%, value%)
  131.          NEXT i
  132.  
  133.  
  134.  
  135.  
  136.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  137.  
  138.     Function: s% = ASCII(st$)
  139.     object code: ascii.obj
  140.  
  141.          ASCII returns the ASCII value of the first letter of the string
  142.     st$.  This is similar to BASIC's ASC(st$) function, except that ASCII
  143.     returns -1 if str$ is a nul string, instead of stopping the program
  144.     with an "Illegal Function Call" error message or requiring BASIC's
  145.     ON ERROR.
  146.  
  147.     Example:
  148.         REM $INCLUDE: 'qlib.bi'
  149.         s% = ASCII(st$)
  150.  
  151.  
  152.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  153.  
  154.     Function: i% = Bit2INT(bitstring$)
  155.     object code: bit2int.obj
  156.  
  157.          Bit2INT converts a bit pattern as represented in the string
  158.     bitstring$ into an integer value.  This may be used to develop bit
  159.     patterns for graphics applications.  If Bit2INT is used for this purpose,
  160.     bitstring$ should be no longer than 8 characters.
  161.     Bit2INT examines each character in bitstring$ and sets bits in bitvalue%
  162.     corresponding to non-zero characters in bitstring$.
  163.  
  164.     Example:
  165.          REM $INCLUDE: 'qlib.bi'
  166.          bitstring1$ = "10101010"
  167.          bitstring2$ = "01010101"
  168.          bitvalue1% = Bit2INT(bitstring1$)
  169.          bitvalue2% = Bit2INT(bitstring2$)
  170.          pattern$ = CHR$(bitvalue1%) + CHR$(bitvalue2%)
  171.          CALL FillPattern(pattern$)              ' this results in a fill
  172.               .                                  ' pattern of alternating
  173.               .                                  ' light and dark pixels.
  174.               .                                  ' See FillPattern in
  175.                                ' GRAPHICS.DOC
  176.  
  177.  
  178.  
  179.  
  180.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  181.  
  182.     Subroutine: CombineINTArray(s0%, p0%, s1%, p1%, n%, add%)
  183.     object file: combine0.obj
  184.  
  185.     Subroutine: CombineLNGArray(s0%, p0%, s1%, p1%, n%, add%)
  186.     object file: combine1.obj
  187.  
  188.     Subroutine: CombineSNGArray(s0%, p0%, s1%, p1%, n%, add%)
  189.     object file: combine2.obj
  190.  
  191.     Subroutine: CombineDBLArray(s0%, p0%, s1%, p1%, n%, add%)
  192.     object file: combine3.obj
  193.  
  194.      CombineArray subroutines add Array1() to Array0() or subtract
  195.     Array1() from Array0().  Array0() is altered; Array1() remains 
  196.     unchanged.  If add% = 1, Array1() is added to Array0().  If 
  197.     add% = -1, Array1() is subtracted from Array0().  N% is the
  198.     number of array elements.  CombineINTArray is for INTEGER arrays,
  199.     CombineLNGArray is for LONG integer arrays, CombineSNGArray is for
  200.     SINGLE arrays and CombineDBLArray is for DOUBLE arrays.  Note that
  201.     BOTH arrays must be the same type.  CombineSNGArray and CombineDBLArray
  202.     use the 8087 if available or BASIC's 8087 emulator if no math
  203.     coprocessor is in the computer.  To preserve compatability with
  204.     future versions of CombineArray subroutines, use only add% = 1
  205.     or add% = -1.
  206.  
  207.     Example:
  208.         DEFINT A-Z
  209.         DIM Array0(99), Array1(99)
  210.           .    ' program establishes values of arrays
  211.           .
  212.           .
  213.      s0% = VARSEG(Array0(0)): p0% = VARPTR(Array0(0))
  214.      S1% = VARSEG(Array1(0)): p1% = VARPTR(Array1(0))
  215.      n% = 100  ' all array elements, from 0 through 99
  216.      type% = 1 ' add array1 to array0
  217.      CALL CombineINTArray(s0%, p0%, s1%, p1%, n%, type%)
  218.  
  219.  
  220.  
  221.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  222.  
  223.     Subroutine: CopyMem(fromSEG%, fromOFF%, toSEG%, toOFF%, bytes%, crt%)
  224.     object file: copymem.obj
  225.  
  226.          Copies data from one part of memory to another.  You supply
  227.     the source segment and offset, destination segment and offset, and 
  228.     number of bytes to move (0 - 32767).  This can be used to duplicate
  229.     numeric arrays, or to copy to or from the video buffer.  CopyMem will
  230.     wait for retrace periods before copying any data if crt% = -1 (to avoid
  231.     "snow" when copying to or from CGA video memory).  Use crt% = 0 if not
  232.     copying to or from video memory.
  233.  
  234.     Example:
  235.          DIM Array1%(1999)        ' 4000-byte array
  236.          CALL GetCRT(crt%)        ' crt% = -1 if monitor = CGA
  237.          fromSEG% = &HB800        ' CGA / EGA video memory segment
  238.          fromOFF% = 0             ' start of video memory buffer
  239.          bytes% = 4000            ' 25 rows x 160 bytes per row
  240.          toSEG% = VARSEG(Array1%(0))
  241.          toOFF% = VARPTR(Array1%(0))
  242.          CALL CopyMem(fromSEG%, fromOFF%, toSEG%, toOFF%, bytes%, crt%)
  243.          REM  we just stored the entire screen in array Array1%()
  244.  
  245.  
  246.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  247.  
  248.     Subroutine: Date2LNG(month%, day% year%, date&)
  249.     Subroutine: LNG2Date(month%, day% year%, date&)
  250.     object file: date2lng.obj
  251.  
  252.          Date2LNG compresses a date into a long integer for storage.  LNG2Date
  253.     restores the date from the compressed value.
  254.  
  255.     Example:
  256.          month% = 7
  257.          day% = 20
  258.          year% = 2052
  259.          CALL Date2LNG(month%, day%, year%, date&)
  260.     
  261.  
  262.  
  263.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  264.  
  265.     Function: day$ = DayName(day%)
  266.     object file: dname.obj (q$mname.obj, strncpy.obj)
  267.  
  268.          DayName returns an ASCII string with the day name, given
  269.     a day% number from 1 to 7.  Unlike an array of day names
  270.     dimesioned by BASIC and stored as an array of variable-length strings,
  271.     DayName's data is stored outside of DGROUP, freeing that precious
  272.     space for other string data.
  273.  
  274.     Example:
  275.         REM $INCLUDE: 'qlib.bi'
  276.         day% = 1                 ' Sunday
  277.         PRINT DayName(day%)      ' prints "Sunday"
  278.  
  279.  
  280.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  281.  
  282.     Function: day% = DayOfWeek(month%, date%, year%)
  283.     object file: dayoweek.obj
  284.  
  285.          Returns the day of week (1=Sunday through 7=Saturday) given a
  286.     valid date.  Valid dates are from Jan 1, 1980 through Dec 31, 2099.
  287.     Day% = 0 if the date passed to the subroutine is not valid.
  288.  
  289.     Example:
  290.          REM $INCLUDE: 'qlib.bi'
  291.          month% = 2
  292.          date% = 2
  293.          year% = 1990         ' ground hog's day, 1990
  294.          day% = DayOfWeek(month%, date%, year%)
  295.  
  296.  
  297.  
  298.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  299.  
  300.     Function: n$ = DBL2STR(n#, dec%, opt%)
  301.     object files: dbl2str.obj (q$sfmt.obj)
  302.  
  303.     Function: n$ = SNG2STR(n!, dec%, opt%)
  304.     object files: sng2str.obj (q$sfmt.obj)
  305.  
  306.          DBL2STR and SNG2STR convert a DOUBLE or SINGLE number to an
  307.     ASCII string usable by QPrint, GPrint and other QLIB subroutines,
  308.     with formatting options.  n# or n! is the number you want converted,
  309.     dec% is the number of decimal places you want in the string and
  310.     opt% is an option code.
  311.  
  312.     DBL2STR and SNG2STR options are:
  313.  
  314.     1 = negative numbers enclosed by parentheses
  315.     2 = thousands separated by commas
  316.     4 = truncate decimals (default is round decimals)
  317.  
  318.     options may be combined with BASIC's OR operator.
  319.  
  320.     Example:
  321.         REM $INCLUDE: 'qlib.bi'
  322.         n! = -1234.567
  323.         dec% = 2                      ' 2 decimal places
  324.         opt% = 1 OR 2                 ' parentheses and commas
  325.         n$ = SNG2STR(n!, dec%, opt%)  ' n$ = "(1,234.57)"
  326.  
  327.  
  328.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  329.  
  330.     Subroutine: DelArray2(VARSEG(a%(0)), VARPTR(a%(0)), i%, n%)
  331.     Subroutine: DelArray4(VARSEG(a!(0)), VARPTR(a!(0)), i%, n%)
  332.     Subroutine: DelArray8(VARSEG(a#(0)), VARPTR(a#(0)), i%, n%)
  333.     object file: delarray.obj
  334.  
  335.       DelArray subroutines delete array element a(i) from the array
  336.     and close the resulting gap.  n% is the maximum array subscript.
  337.     DelArray2 is used with 2-byte data, such as INTEGERs.  DelArray4 is
  338.     for 4-byte data, such as SINGLE or LONG.  DelArray8 is for 8-byte
  339.     data, such as DOUBLE or BC7's CURRENCY data type.
  340.  
  341.     Example:
  342.      DIM a%(99)             ' array of 100 elements, a(0) -> a(99)
  343.           .              ' INTEGER data type
  344.           .
  345.           .
  346.      REM  I want to delete a%(14) and move a%(15) through a%(99) up
  347.      i% = 14: n% = 99
  348.      CALL DelArray2(VARSEG(a(0)), VARPTR(a(0)), i%, n%)
  349.  
  350.  
  351.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  352.  
  353.     Subroutine: DelVSTRArray(VARPTR(a$(0)), i%, n%)
  354.     object file: delvstr.obj
  355.  
  356.         Deletes a$(i) from an array of variable-length strings, and moves
  357.     a$(i+1) through a$(n) forward.  a$(n) will be moved to a$(n-1), and
  358.     the new a$(n) will be a nul string.
  359.  
  360.     Example:
  361.         DIM a$(100)
  362.                   .
  363.                   .
  364.                   .
  365.         i% = 10: n% = 100
  366.         CALL DelVSTRArray(VARPTR(a$(0)), i%, n%)
  367.  
  368.  
  369.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  370.  
  371.     Function: i% = Find1(s%, p%, n%, value%)
  372.     object file: find1.obj
  373.  
  374.     Function: i% = Find2(s%, p%, n%, value%)
  375.     object file: find2.obj
  376.  
  377.     Function: i% = Find4(s%, p%, n%, value&|value!)
  378.     Function: i% = Find8(s%, p%, n%, value#|value@)
  379.     object file: find4.obj
  380.  
  381.         Find1, Find2, Find4 and Find8 find the first occurance of a value
  382.     in an array.  Find1 is for QLIB's SHORT arrays, Find2 is for INTEGER
  383.     arrays, Find4 is for LONG arrays or for SINGLE arrays, Find8 is for
  384.     DOUBLE or BC7's CURRENCY arrays.  Note that value's data type must
  385.     match the array's data type.  I% is returned -1 if value is not found
  386.     or if n% = 0.
  387.  
  388.     Example:
  389.         REM $INCLUDE: 'qlib.bi'
  390.                               ' QLIB.BI has all the function declarations
  391.         DIM a#(99)            ' 100 DOUBLE values
  392.         n% = 100              ' gonna search the whole array
  393.           .
  394.           .
  395.           .
  396.         s% = VARSEG(a#(0)): p% = VARPTR(a#(0))
  397.                               ' establish pointers to array, start at a#(0)
  398.         value# = .123456789#
  399.         i% = Find8(s%, p%, n%, value#)
  400.         IF i% = -1 GOTO Drat  ' value# isn't in the array
  401.                               '  else a#(i%) = value#
  402.  
  403.  
  404.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  405.  
  406.     Subroutine: FreeMem(segmentaddr%)
  407.     object file: allocmem.obj (q$alloc.obj)
  408.  
  409.         FreeMem releases memory blocks allocated by QLIB (such as by
  410.     AllocMem, ScreenMem and WindowMem).  If you do not release the
  411.     memory block after you are done using it, that memory will not be
  412.     available to your program for other uses.  See ScreenSave,
  413.     ScreenRestore and ScreenMem in VIDEO.DOC for an example of FreeMem's
  414.     use.  See also AllocMem in DATA.DOC.
  415.  
  416.  
  417.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  418.  
  419.     Subroutine: GetTime(hour%, min%, sec%)
  420.     object file: gettime.obj
  421.  
  422.         GetTime returns the system time.  Hour% is from 0 to 23, min%
  423.     and sec% are 0 through 59.
  424.  
  425.     Example:
  426.         CALL GetTime(hour%, min%, sec%)
  427.  
  428.  
  429.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  430.  
  431.     Subroutine: InsArray2(s%, p%, i%, n%, value%)
  432.     Subroutine: InsArray4(s%, p%, i%, n%, value!)
  433.     Subroutine: InsArray8(s%, p%, i%, n%, value#)
  434.     object file: insarray.obj
  435.  
  436.         InsArray subroutines insert value% (or !, @, #, &) in an array of
  437.     n% elements at position i%, moving a(i) through a(n-1) to a(i+1) through
  438.     a(n) to make space.  The previous a(n) is lost.  InsArray2 is for 2-byte
  439.     INTEGER data, InsArray4 is for 4-byte SINGLE or LONG data, and InsArray8
  440.     is for 8-byte DOUBLE or BC7's CURRENCY data.  Note that the data type of
  441.     value must be the same as the data type of the array.
  442.  
  443.     Example:
  444.         DIM a&(100)
  445.               .
  446.               .
  447.               .
  448.         value& = 1019876               ' want to put this in the array
  449.         i% = 75                        ' at a(75), moving a(75) through
  450.         n% = 100                       ' a(99) to make room.
  451.         s% = VARSEG(a&(0)): p% = VARPTR(a&(0))
  452.         CALL InsArray4(VARSEG(s%, p%, i%, n%, value&)
  453.  
  454.  
  455.  
  456.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  457.  
  458.     Subroutine: InsVSTRArray(VARPTR(a$(0)), i%, n%, newstring$)
  459.     object file: insvstr.obj
  460.  
  461.         Similar to the InsArray subroutines, above, but works with an
  462.     array of variable-length string data.  n% is the total number of
  463.     strings in the array, newstring$ is inserted in the array at a$(i),
  464.     a$(i) through a$(n-1) are moded to a$(i+1) through a$(n), and the
  465.     previous a$(n) is lost.
  466.  
  467.     Example:
  468.     DIM a$(40)
  469.     newstring$ = "the new string data"
  470.     i% = 20: n% = 40
  471.     CALL InsVSTRArray(VARPTR(a$(0)), i%, n%, newstring$)
  472.  
  473.  
  474.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  475.  
  476.     Function: c$ = InsertString(a$, b$, i%)
  477.     object file: insstr.obj
  478.  
  479.         InsertString inserts b$ in a$ at position i% in a$.
  480.  
  481.     Example:
  482.         REM $INCLUDE: 'qlib.bi'
  483.         a$ = "a day in paradise"
  484.         b$ = "nother"
  485.         i% = 2
  486.         c$ = InsertString(a$, b$, i%)
  487.         REM  returns c$ = "another day in paradise"
  488.  
  489.  
  490.  
  491.  
  492.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  493.  
  494.     Function: i% = InString(search$, pattern$, start%)
  495.     object files: instring.obj (q$strstr.obj)
  496.  
  497.     Function: i% = InStringR(search$, pattern$, start%)
  498.     object files: instrr.obj (q$srev.obj, q$strstr.obj)
  499.  
  500.     Function: i% = InString2(search$, pattern$, start%)
  501.     object files: instr2.obj (q$tstr.obj, q$strstr.obj)
  502.  
  503.     Function: i% = InString2R(search$, pattern$, start%)
  504.     object files: instr2r.obj (q$tstr.obj, q$srev.obj, q$strstr.obj)
  505.  
  506.         Similar to BASIC's INSTR function, InString will find the first
  507.     occurrence of pattern$ in search$, and will return position% = position
  508.     in search$ where pattern$ matches.  Start% is the position in search$
  509.     where InString begins looking for pattern$.
  510.         InString2 is case-insensitive, meaning that upper case A-Z are
  511.     treated the same as lower case a-z.
  512.         InStringR (Reverse) searches from the end to the start of search$.
  513.     Start% is the position in search$ where InStringR begins it's search.
  514.     To search the entire search$, start% should be LEN(search$) or greater.
  515.         InString2R is a case-insensitive reverse INSTR-like function.
  516.  
  517.     Example:
  518.          REM $INCLUDE: 'qlib.bi'
  519.          search$ = "This is a test string"
  520.          pattern$ = "is"
  521.          start% = 1               ' begin search at first char in Search$
  522.          position% = InString(search$, pattern$, start%)
  523.                                   ' returns position% = 3
  524.  
  525.          start% = 4               ' begin search at fourth char in Search$
  526.          position% = InString(search$, pattern$, start%)
  527.                                   ' returns position% = 6
  528.  
  529.  
  530.  
  531.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  532.  
  533.     Function: i% = InStringCount(search$, pattern$, start%)
  534.     object files: instr3.obj (q$strstr.obj)
  535.  
  536.         InStringCount counts the number of times pattern$ is found in
  537.     search$, beginning at start% in search$.
  538.  
  539.     Example:
  540.          REM $INCLUDE: 'qlib.bi'
  541.          search$ = "There is a moose with the mouse"
  542.          pattern$ = " mo"
  543.          start% = 1               ' search entire pattern$
  544.          count% = InStringCount(search$, pattern$, start%)
  545.          REM  in this case count% = 2
  546.  
  547.  
  548.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  549.  
  550.     Subroutine: INT2SNG(a%, a!)
  551.     object file: int2sng.obj
  552.  
  553.     Subroutine: LNG2SNG(a&, a!)
  554.     object file: lng2sng.obj
  555.  
  556.          INT2SNG and LNG2SNG are similar to BASIC's a! = CSNG(a%) and
  557.     a! = CSNG(a&) commands, except they are up to 30% faster than
  558.     QuickBASIC.  8087 not required.
  559.  
  560.     Example:
  561.          a% = 12345
  562.          CALL INT2SNG(a%, a!)    ' a! now equals 12345
  563.  
  564.  
  565.  
  566.  
  567.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  568.  
  569.     Function: n$ = INT2STR(a%, options%)
  570.     object file: int2str.obj
  571.  
  572.     Function: n$ = LNG2STR(a&, options%)
  573.     object file: lng2str.obj
  574.  
  575.          INT2STR and LNG2STR are similar to BASIC's STR$(a%) function,
  576.     with the addition of flexible number format options.  Number$ may be used
  577.     with QLIB's video output subroutines.  Formatting options include negative
  578.     numbers in accounting format (enclosed by parentheses) and commas after
  579.     thousands.  LNG2STR's number$ is 17 characters long, and INT2STR creates
  580.     a string 10 characters long.  In both cases, the number will be right-
  581.     justified in number$.  If a% (or a&) is non-negative and accounting
  582.     format is selected, a space will be included to the right of the number
  583.     to justify it with negative numbers in the same format.
  584.  
  585.     Example:
  586.          REM $INCLUDE: 'qlib.bi'
  587.          a% = 24561
  588.          options% = 2              ' include commas
  589.          options% = options% OR 1  ' accounting format
  590.          number$ = INT2STR(a%, options%)
  591.          CALL Qprint(number$, etc...
  592.  
  593.  
  594.  
  595.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  596.  
  597.     Subroutine: LNG2Date(month%, day%, year%, date&)
  598.  
  599.          See Date2LNG
  600.  
  601.  
  602.  
  603.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  604.  
  605.     Function: i% = MaxINTArray(aSEG%, aPTR%, n%)
  606.     Function: i% = MinINTArray(aSEG%, aPTR%, n%)
  607.     object files: (medium model) maxmin0.obj
  608.                   (huge model) maxmin0.obj, lowds2hi.obj
  609.  
  610.     Function: i% = MaxLNGArray(aSEG%, aPTR%, n%)
  611.     Function: i% = MinLNGArray(aSEG%, aPTR%, n%)
  612.     object files: (medium model) maxmin1.obj
  613.                   (huge model) maxmin1.obj, lowds2hi.obj
  614.  
  615.     Function: i% = MaxSNGArray(aSEG%, aPTR%, n%)
  616.     object files: (medium model) maxsng.obj
  617.                   (huge model) maxsng.obj, lowds2hi.obj
  618.  
  619.     Function: i% = MaxDBLArray(aSEG%, aPTR%, n%)
  620.     object files: (medium model) maxdbl.obj
  621.                   (huge model) maxdbl.obj, lowds2hi.obj
  622.  
  623.     Function: i% = MinSNGArray(aSEG%, aPTR%, n%)
  624.     object files: (medium model) minsng.obj
  625.                   (huge model) minsng.obj, lowds2hi.obj
  626.  
  627.     Function: i% = MinDBLArray(aSEG%, aPTR%, n%)
  628.     object files: (medium model) mindbl.obj
  629.                   (huge model) mindbl.obj, lowds2hi.obj
  630.  
  631.     INT, LNG, SNG and DBL functions find the array element with
  632.     maximum or minimum value between begin% and begin + n%.
  633.     80x87 not required.  These functions are very fast.
  634.  
  635.     Example:
  636.          REM $INCLUDE: 'qlib.bi'
  637.          DIM a%(99)      ' 100 element integer array
  638.               .
  639.               .
  640.               .
  641.          begin% = 0      ' start with the first array element
  642.          n% = 90         ' look at the first 90 array elements
  643.                          ' a%(0) -> a%(89)
  644.          aSEG% = VARSEG(a%(begin%))
  645.          aPTR% = VARPTR(a%(begin%))
  646.          i% = MaxINTArray(aSEG%, aPTR%, n%)
  647.          PRINT "the maximum value is"; a%(i% + begin%)
  648.  
  649.  
  650.  
  651.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  652.  
  653.     Function: i% = MaxDBLb(seg%, ptr%, n%, bytes%)
  654.     object files: (medium model) maxdbl.obj
  655.                   (huge model) maxdbl.obj, lowds2hi.obj
  656.  
  657.     Function: i% = MinDBLb(seg%, ptr%, n%, bytes%)
  658.     object files: (medium model) mindbl.obj
  659.                   (huge model) mindbl.obj, lowds2hi.obj
  660.  
  661.     Function: i% = MaxINTb(seg%, ptr%, n%, bytes%)
  662.     Function: i% = MinINTb(seg%, ptr%, n%, bytes%)
  663.     object files: (medium model) maxmin0.obj
  664.                   (huge model) maxmin0.obj, lowds2hi.obj
  665.  
  666.     Function: i% = MaxLNGb(seg%, ptr%, n%, bytes%)
  667.     Function: i% = MinLNGb(seg%, ptr%, n%, bytes%)
  668.     object files: (medium model) maxmin1.obj
  669.                   (huge model) maxmin1.obj, lowds2hi.obj
  670.  
  671.     Function: i% = MaxSNGb(seg%, ptr%, n%, bytes%)
  672.     object files: (medium model) maxsng.obj
  673.                   (huge model) maxsng.obj, lowds2hi.obj
  674.  
  675.     Function: i% = MinSNGb(seg%, ptr%, n%, bytes%)
  676.     object files: (medium model) minsng.obj
  677.                   (huge model) minsng.obj, lowds2hi.obj
  678.  
  679.     Similar to MaxINTArray and MinINTArray, but the byte increment between
  680.     array elements to search is specified.  This is handy for
  681.     multi-dimensional arrays.  This is best explained with an example.
  682.  
  683.     (example on next page)
  684.  
  685.  
  686.  
  687.     (MaxINTb example)
  688.  
  689.     DEFINT A-Z
  690.     DECLARE FUNCTION MaxINTb% (s, p, n, bytes%)
  691.  
  692.     ' dimension a 40- by 40 integer array
  693.     DEFINT A-Z
  694.     DIM a(39, 39)
  695.  
  696.     ' fill the array with random numbers
  697.         FOR j = 0 TO 39
  698.         FOR i = 0 TO 39: a(i, j) = CINT(100 * RND): NEXT i
  699.         NEXT j
  700.  
  701.     ' clear the screen to show the results
  702.     ' I want to find the maximum value between a(20, 0) and a(20, 39)
  703.         CLS
  704.         FOR i = 0 TO 39: PRINT a(20, i): NEXT i
  705.  
  706.     ' search 40 data points
  707.         n = 40
  708.  
  709.     ' get segment and offset address for a(20, 0)
  710.         s = VARSEG(a(20, 0)): p = VARPTR(a(20, 0))
  711.  
  712.     ' calculate the byte space between successive array elements
  713.     ' this works whether you're in row-major or column-major mode
  714.     ' recall that p% = VARPTR(a(20, 0))
  715.         bytes% = VARPTR(a(20, 1)) - p%
  716.  
  717.     ' call the function; the array element with the highest value from
  718.     ' a(20, 0) to a(20, 39) is a(20, (0+i))
  719.         i = MaxINTb(s, p, n, b)
  720.         PRINT: PRINT a(20, i);
  721.  
  722.  
  723.  
  724.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  725.  
  726.     Function: i% = MaxVSTRArray(o%, n%)  (QB4.x only)
  727.     Function: i% = MinVSTRArray(o%, n%)  (QB4.x only)
  728.     object file: maxmin5.obj
  729.  
  730.          Finds longest or shortest string in a variable-length string
  731.     array.  o% = VARPTR(a$(start%)), and n% is the number of array elements
  732.     to search.
  733.  
  734.     Example:
  735.          REM $INCLUDE: 'qlib.bi'
  736.          DIM A$(99)        ' an array of 100 variable-length strings
  737.              .             ' program establishes strings
  738.              .
  739.              .
  740.          i% = MaxVSTRArray(VARPTR(a$(0)),100)
  741.          PRINT "The longest string in the array is " + a$(i%)
  742.  
  743.  
  744.  
  745.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  746.  
  747.     Function: month$ = MonthName(month%)
  748.     Object file: mname.obj (q$mname.obj, strncpy.obj)
  749.  
  750.          MonthName returns an ASCII string with the month name, given
  751.     a month% number from 1 to 12.  Unlike an array of month names
  752.     dimesioned by BASIC and stored as an array of variable-length strings,
  753.     MonthName's data is stored outside of DGROUP, freeing that precious
  754.     space for other string data.
  755.  
  756.     Example:
  757.         REM $INCLUDE: 'qlib.bi'
  758.         month% = 1               ' January
  759.         PRINT MonthName(month%)  ' prints "January"
  760.  
  761.  
  762.  
  763.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  764.  
  765.     Subroutine: MulINTArray(aSEG%, aPTR%, n%, number!)
  766.     Subroutine: MulLNGArray(aSEG%, aPTR%, n%, number!)
  767.     Subroutine: MulSNGArray(aSEG%, aPTR%, n%, number!)
  768.     Subroutine: MulDBLArray(aSEG%, aPTR%, n%, number#)
  769.     Subroutine: MulINTb(aSEG%, aPTR%, n%, number!, bytes%)
  770.     Subroutine: MulLNGb(aSEG%, aPTR%, n%, number!, bytes%)
  771.     Subroutine: MulSNGb(aSEG%, aPTR%, n%, number!, bytes%)
  772.     Subroutine: MulDBLb(aSEG%, aPTR%, n%, number#, bytes#)
  773.     object file: mularray.obj
  774.  
  775.          MulArray subroutines multiply n% elements of an array
  776.     by a constant real number.     MulArray subroutines use the 8087 if
  777.     available, or use the 8087 emulator if no 8087 is in the computer.
  778.  
  779.     Note that DBL arrays are multiplied by a double-precision real number 
  780.     (number#), all other data types are multiplied by a single-precision
  781.     real number (number!).  With Mul???b subroutines, you must specify
  782.     the byte increment between successive data elements.
  783.  
  784.     Example:
  785.          DIM a#(99)     ' 100-element array, double precision
  786.               .
  787.               .
  788.               .
  789.          number# = 4.78
  790.          n% = 50        ' multiply a#(0) through a#(49) by number#
  791.          aSEG% = VARSEG(a#(0))  ' aSEG% = segment where a#(0) is stored
  792.          aPTR% = VARPTR(a#(0))  ' aPTR% = offset of a#(0) in aSEG%
  793.          CALL MulDBLArray(aSEG%, aPTR%, n%, number#)
  794.  
  795.  
  796.  
  797.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  798.  
  799.     Function: ReadSShort(ArraySeg%, ArrayPtr%, ShortOffset%
  800.     Function: ReadUShort(ArraySeg%, ArrayPtr%, ShortOffset%)
  801.     Subroutine: WriteShort(ArraySeg%, ArrayPtr%, ShortOffset%, value%)
  802.     object file: shortint.obj
  803.  
  804.          Read/WriteShort subroutines provide support for short integers,
  805.     allowing some integer arrays to be compressed to half the normal size.
  806.     In order to use these subroutines, the data must be within the ranges
  807.     shown:
  808.  
  809.     Signed short integers: -128 to 127      (use ReadSShort)
  810.     unsigned short integers:  0 to 255      (use ReadUShort)
  811.  
  812.     A normal array must be dimensioned before these subroutines can be used.
  813.     WriteShort stores value% in the array at byte offset ShortOffset%, and
  814.     ReadShort subroutines return the number at ShortOffset% as value%.
  815.     Be sure you know what you're doing if you use these subroutines.
  816.  
  817.     Example:
  818.     REM $INCLUDE: 'qlib.bi'
  819.     REM  I want to store 300 integers in a Short integer array.
  820.     REM  The data I'm using falls within the range of values for
  821.     REM  short unsigned integers, 0 to 255.
  822.     REM  First, I need to dimension an array to hold the data.
  823.  
  824.     DIM array%(149)
  825.  
  826.     REM  150 integer array elements, 0 to 149, = 300 short integers, 0 to 299
  827.     REM  The example below stores value% as ShortArray(200)
  828.  
  829.     value% = 125
  830.     n% = 200
  831.     ArraySeg% = VARSEG(array%(0))
  832.     ArrayPtr% = VARPTR(array%(0))
  833.     CALL WriteShort(ArraySeg%, ArrayPtr%, n%, value%)
  834.  
  835.     REM  now I'll read the value back
  836.     ArraySeg% = VARSEG(array%(0))
  837.     ArrayPrt% = VARPTR(array%(0))
  838.     value% = ReadUShort(ArraySeg%, ArrayPtr%, n%)
  839.  
  840.  
  841.  
  842.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  843.  
  844.     Function: c$ = ReplaceString$(a$, b$, i%, n%)
  845.     object file: replace.obj
  846.  
  847.         ReplaceString replaces n% characters of a$ with b$, placing b$ at
  848.     i in a$.  See the example if you're still confused.
  849.  
  850.     Example:
  851.         a$ = "a blue tree"
  852.         b$ = "purple"
  853.         i% = InString(a$, "blue", 1) ' find start of "blue" in a$
  854.         n% = 4                       ' length of "blue"
  855.         PRINT ReplaceString(a$, b$, i%, n%)
  856.                                      ' prints "a purple tree"
  857.  
  858.  
  859.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  860.  
  861.     Subroutine: Scramble(str$)
  862.     Subroutine: UnScramble(str$)
  863.     object file: scramble.obj
  864.  
  865.          Scramble does what its name implies; it scrambles the bits in the
  866.     string str$ to make it unreadable.  This can be handy for hiding
  867.     passwords.  Since some characters in str$ may be translated to end-of-file
  868.     or carriage return marks, a scrambled string saved to disk should be
  869.     written into a fixed field file or random-access file, not a sequential
  870.     file.  UnScramble should be used to restore str$.
  871.  
  872.     Example:
  873.          password$ = "Chocolate Ice Cream"
  874.          CALL Scramble(password$)           ' password$ is now unreadable
  875.               .
  876.               .
  877.               .
  878.          CALL UnScramble(password$)         ' password is restored
  879.  
  880.  
  881.  
  882.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  883.  
  884.     Subroutine: SetArray1(segment%, ptr%, n%, value%)
  885.     object file: set2.obj
  886.  
  887.     Subroutine: SetArray1b(segment%, ptr%, n%, value%, bytes%)
  888.     object files: (medium model) set2b.obj
  889.                   (huge model) set2b.obj, lowes2hi.obj
  890.  
  891.     Subroutine: SetArray2(segment%, ptr%, n%, value%)
  892.     object file: set2.obj
  893.  
  894.     Subroutine: SetArray2b(segment%, ptr%, n%, value%, bytes%)
  895.     object files: (medium model) set2.obj
  896.                   (huge model) set2.obj, lowes2hi.obj
  897.  
  898.     Subroutine: SetArray4(segment%, ptr%, n%, value![or value&])
  899.     Subroutine: SetArray8(segment%, ptr%, n%, value#[or value@])
  900.     Subroutine: SetArray4b(segment%, ptr%, n%, value![or value&], bytes%)
  901.     Subroutine: SetArray8b(segment%, ptr%, n%, value#[or value@], bytes%)
  902.     object files: (medium model) set4.obj
  903.                   (huge model) set4.obj, lowes2hi.obj
  904.  
  905.     Set n% elements of an array to a value.  Note that the value passed to
  906.     the subroutine is the same data type as the array.  SetArray1 is for
  907.     QLIB's short integer arrays, SetArray2 is for INTEGER arrays, SetArray4
  908.     is for LONG or SINGLE arrays, and SetArray8 is for DOUBLE or BC7's
  909.     CURRENCY arrays.  With SetArray1b, SetArray2b, SetArray4b and
  910.     SetArray8b, the increment between array elements (bytes%) must be
  911.     specified.
  912.  
  913.     Example 1:
  914.          DIM a%(99): n%=100      ' integer array of 100 elements
  915.            .
  916.            .
  917.          value% = -6
  918.          s% = VARSEG(a%(0))    ' starting with first array element
  919.          p% = VARPTR(a%(0))
  920.          CALL SetArray2(s%, p%, n%, value%)
  921.          REM  we just set each element of the array a%() to -6
  922.  
  923.     Example 2:
  924.          DIM a&(9999): n% = 1000  ' long integer array of 10000 elements
  925.           .                       ' each array element is 4 bytes long
  926.           .
  927.          value& = 140
  928.          bytes% = 8               ' set only every other array element
  929.          s% = VARSEG(a&(0))
  930.          p% = VARPTR(a&(0))
  931.          CALL SetArray4b(s%, p%, n%, value&, bytes%)
  932.          REM  we just set 1000 elements of the array a&() to 140
  933.  
  934.  
  935.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  936.  
  937.     Subroutine: ShiftCUR(value@, factor%)  (BC7/QBX only)
  938.     Subroutine: SShiftCUR(value@, factor%) (BC7/QBX only)
  939.     object file: shiftcur.obj
  940.  
  941.     Subroutine: ShiftINT(value%, factor%)
  942.     Subroutine: SShiftINT(value%, factor%)
  943.     object file: shift.obj
  944.  
  945.     Subroutine: ShiftLNG(value&, factor%)
  946.     Subroutine: SShiftLNG(value&, factor%)
  947.     object file: shiftlng.obj
  948.  
  949.          Shifts all the bits in an integer factor% times.  If factor% is
  950.     positive, the bits are shifted LEFT.  This effectively multiplies the
  951.     value by a power of two in most instances.  If factor% is negative, the
  952.     bits are shifted RIGHT ABS(factor%) times.  This is similar in effect to
  953.     an integer divide by a power of two.  Shift and SShift subroutines differ
  954.     in the way negative numbers are treated when shifting right.  Shift will
  955.     replace the bits shifted off the right end of the data with zeros at the
  956.     left, thus making negative numbers do unpredictable things.  SShift
  957.     (Signed Shift) preserves the sign of the original value so that shifting
  958.     the value right effectively divides the value by a factor% value of two.
  959.     Note, however, that repeated SShifting of a positive value right results
  960.     in value = 0, while a negative value SShifted right repeatedly ends up
  961.     with value = -1.
  962.     
  963.     Example 1:
  964.          VALUE% = 47: factor% = 3
  965.          CALL ShiftINT(VALUE%, factor%)
  966.          REM  we just shifted VALUE% left three bits
  967.          REM  (in this case getting 47 * 2^3, or 376)
  968.  
  969.     Example 2:
  970.          VALUE% = 47: factor% = -3
  971.          CALL ShiftINT(VALUE%, factor%)
  972.          REM  we just shifted VALUE% right 3 bits
  973.          REM  (here getting 47 \ 2^3, or 5)
  974.  
  975.  
  976.  
  977.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  978.  
  979.     Subroutine: ShiftINTArray(aSEG%, aPTR%, n%, factor%, oops%)
  980.     Subroutine: SShiftINTArray(aSEG%, aPTR%, n%, factor%, oops%)
  981.     object file: array1.obj
  982.  
  983.     Subroutine: ShiftLNGArray(aSEG%, aPTR%, n%, factor%, oops%)
  984.     Subroutine: SShiftLNGArray(aSEG%, aPTR%, n%, factor%, oops%)
  985.     object file: lngarray.obj
  986.  
  987.          Shifts the bits of any n% elements of an integer array
  988.     ABS(factor%) times.  Positive values of factor% shift array elements
  989.     LEFT.  This is equivalent to multiplying the element by a factor% power
  990.     of 2 in most instances.  Negative values of factor% cause an integer
  991.     divide by an ABS(factor%) power of 2. OOPS% will be returned -1 if an
  992.     overflow occurred.  Oops% will also be -1 if any negative numbers
  993.     are shifted left, thus the usefulness of oops% in these subroutines is
  994.     limited.  SShiftArray preserves the sign of right-shifted values.
  995.     See SShiftINT for details.
  996.  
  997.     Example:
  998.          DIM a%(100)
  999.          n% = 20
  1000.          factor% = 1
  1001.          aSEG% = VARSEG(a%(0))
  1002.          aOFF% = VARPTR(a%(0))
  1003.          CALL ShiftINTArray(aSEG%, aOFF%, n%, factor%, oops%)
  1004.          IF oops% = -1 THEN PRINT "Oops, must have overflowed somewhere"
  1005.          REM  assuming there were no negative numbers in the array
  1006.  
  1007.  
  1008.  
  1009.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1010.  
  1011.     Function: a% = SNG2INT(a!, oops%)
  1012.     object file: sng2int.obj
  1013.  
  1014.          Copies the integer portion of a single-precision number a! to
  1015.     the integer a%.  This is similar to BASIC's a% = INT(a!) command,
  1016.     except SNG2INT is about 6 times faster without an 8087, and SNG2INT
  1017.     returns the error flag oops% = -1 if a! is too big, instead of crashing
  1018.     the program with an "overflow" error message.  Does not require a math
  1019.     coprocessor.  Range of usable numbers is -32768 to +32767.
  1020.  
  1021.     Example:
  1022.          REM $INCLUDE: 'qlib.bi'
  1023.          a! = 20956.64
  1024.          a% = SNG2INT(a!, oops%)
  1025.          IF oops% THEN              ' results usable?
  1026.              GOTO TooBig            ' argh! try something else
  1027.          ENDIF
  1028.  
  1029.  
  1030.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1031.  
  1032.     Function: a& = SNG2LNG(a!, oops%)
  1033.     object file: sng2lng.obj
  1034.  
  1035.          Copies the integer portion of a single-precision number a! to
  1036.     the long integer a&.  This is similar to BASIC's a& = INT(a!) command,
  1037.     except SNG2LNG is about 3 times faster without an 8087, and SNG2LNG
  1038.     returns the error flag oops% = -1 if a! is too big, instead of crashing
  1039.     the program with an "overflow" error message.  Does not require a math
  1040.     coprocessor.  Range of usable numbers is about -2147483500 to
  1041.     +2147483500.
  1042.  
  1043.     Example:
  1044.          REM $INCLUDE: 'qlib.bi'
  1045.          a! = 209587.64
  1046.          a& = SNG2LNG(a!, oops%)
  1047.          IF oops% THEN              ' results usable?
  1048.              GOTO TooBig            ' argh! try something else
  1049.          ENDIF
  1050.  
  1051.  
  1052.  
  1053.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1054.  
  1055.     Subroutine: SortINTArrayHI(aSEG%, aPTR%, n%)
  1056.     Subroutine: SortINTArrayLO(aSEG%, aPTR%, n%)
  1057.     object file: sortint.obj
  1058.  
  1059.     Subroutine: SortLNGArrayHI(aSEG%, aPTR%, n%)
  1060.     Subroutine: SortLNGArrayLO(aSEG%, aPTR%, n%)
  1061.     object file: sortlng.obj
  1062.  
  1063.     Subroutine: SortDBLArrayHI(aSEG%, aPTR%, n%)
  1064.     object file: sortsng0.obj
  1065.  
  1066.     Subroutine: SortDBLArrayLO(aSEG%, aPTR%, n%)
  1067.     object file: sortsng1.obj
  1068.  
  1069.     Subroutine: SortSNGArrayHI(aSEG%, aPTR%, n%)
  1070.     object file: sortdbl0.obj
  1071.  
  1072.     Subroutine: SortSNGArrayLO(aSEG%, aPTR%, n%)
  1073.     object file: sortdbl1.obj
  1074.  
  1075.  
  1076.         Sorts n% elements of an array.  SortArrayHI subroutines arrange
  1077.     a() in descending order (highest first), SortArrayLO subroutines arrange
  1078.     a() in ascending order.  8087 not required.
  1079.  
  1080.     Example:
  1081.         DIM a%(999)              ' integer array, 1000 elements
  1082.              .                   ' program establishes values
  1083.              .                   ' for a%()
  1084.              .
  1085.         n%=1000                  ' sort all elements from low to high
  1086.         aSEG% = VARSEG(a%(0))
  1087.         aPTR% = VARPTR(a%(0))
  1088.         CALL SortINTArrayLO(aSEG%, aPTR%, n%)
  1089.  
  1090.  
  1091.  
  1092.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1093.  
  1094.     Subroutine: SortVSTRArrayHI(o%, n%)
  1095.     Subroutine: SortVSTRArrayLO(o%, n%)
  1096.     object file: sortvstr.obj
  1097.  
  1098.     Subroutine: SortVSTRArrayHI2(o%, n%)
  1099.     Subroutine: SortVSTRArrayLO2(o%, n%)
  1100.     Object files: sortvst2.obj (maxmin5.obj)
  1101.  
  1102.         These subroutines sort a variable-length string array a$() from
  1103.     low to high or high to low.  Note that for case-sensetive subroutines,
  1104.     "A" < "a" and "A" < "AA".  SortVSTRArray2 subroutines are
  1105.     case-insensetive, so that "A" = "a" and "a" < "AA".  o% is the address
  1106.     of the first element in the string array to be sorted, and n% is the
  1107.     number of strings to sort.
  1108.  
  1109.     Example:
  1110.         DIM a$(149)              ' variable-length string array, 150 strings
  1111.              .                   ' program establishes strings
  1112.              .
  1113.              .
  1114.         start% = 10
  1115.         n% = 140                 ' sort through the remainder of the array
  1116.                                  ' be careful that n% + start% does not
  1117.                                  ' exceed the length of the array, or your
  1118.                                  ' program will crash
  1119.         o% = VARPTR(a$(start%))  ' start the sort with the 11th string
  1120.         CALL SortVSTRArrayLO(o%, n%)
  1121.  
  1122.         
  1123.  
  1124.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1125.  
  1126.     Function: position% = strchr(a$, a%)
  1127.     object file: strchr.asm
  1128.  
  1129.          Searches string a$ for the first occurance of character a%.
  1130.     This is similar to using INSTR(a$, CHR$(a%)) to search for a character,
  1131.     except that strchr is quicker than QuickBASIC.
  1132.  
  1133.     Example:
  1134.         REM $INCLUDE: 'qlib.bi'
  1135.         a$ = "A foggy day"
  1136.         a% = 32                 ' look for first space
  1137.         position% = strchr(a$, a%)
  1138.  
  1139.  
  1140.  
  1141.     Function: a$ = StripChar(s$, t$)
  1142.     object file: strip1.obj
  1143.  
  1144.         Returns a string with all characters of t$ removed from s$.
  1145.  
  1146.     Example:
  1147.         REM $INCLUDE: 'qlib.bi'
  1148.         s$ = "$1,234,567.89"       ' a formatted string representing a number
  1149.         t$ = "$,"                  ' remove the non-numeric characters
  1150.         a$ = StripChar(s$, t$)
  1151.         PRINT a$       ' prints "1234567.89"
  1152.  
  1153.  
  1154.  
  1155.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1156.  
  1157.     Function: total# = SumINTArray(aSEG%, aPTR%, n%)
  1158.     object files: sumi2.obj (sumarray.obj)
  1159.  
  1160.     Function: total# = SumLNGArray(aSEG%, aPTR%, n%)
  1161.     object files: sumi4.obj (sumarray.obj)
  1162.  
  1163.     Function: total# = SumSNGArray(aSEG%, aPTR%, n%)
  1164.     object files: sumf4.obj (sumarray.obj)
  1165.  
  1166.     Function: total# = SumDBLArray(aSEG%, aPTR%, n%)
  1167.     object files: sumf8.obj (sumarray.obj)
  1168.  
  1169.          Adds n% array elements starting with a(start%) and returns the
  1170.     total as a real number.  Note that the total is a double-precision real
  1171.     number for all SumArray routines.  SumArray subroutines use the 80x87 if
  1172.     available, or use the 8087 emulator if no 80x87 is in the computer.
  1173.  
  1174.     Example:
  1175.         REM $INCLUDE: 'qlib.bi'
  1176.         DIM a#(99)     ' 100-element array, double precision
  1177.              .
  1178.              .
  1179.              .
  1180.         start% = 10
  1181.         n% = 50        ' total a#(10) through a#(59)
  1182.         aSEG% = VARSEG(a#(start%))  ' aSEG% = segment where a#(10) is stored
  1183.         aPTR% = VARPTR(a#(start%))  ' aPTR% = offset of a#(10) in aSEG%
  1184.         total# = SumDBLArray(aSEG%, aPTR%, n%)
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1190.  
  1191.     Subroutine: Today(month%, day%, year%, weekday%)
  1192.     object file: today.obj
  1193.  
  1194.           Returns integer values for month (1 - 12), day of month (1 - 31),
  1195.     year (1980 - 2099), and day of week (1 - 7, Sunday through Saturday)
  1196.     from the system clock.
  1197.  
  1198.     Example:
  1199.          CALL Today(month%, day%, year%, weekday%)
  1200.  
  1201.  
  1202.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1203.  
  1204.     Function: l% = TrimRight(str$)
  1205.     object file: trimr.obj
  1206.  
  1207.           TrimRight returns the length l% of a string without its trailing
  1208.     blank spaces.  This is similar to BASIC's RTRIM$ function.
  1209.  
  1210.     Example:
  1211.           REM $INCLUDE: 'qlib.bi'
  1212.              .
  1213.              .
  1214.              .
  1215.           length$ = TrimRight(st$)
  1216.           st$ = LEFT$(st$, length%)
  1217.           REM  This example is equivalent to BASIC's st$ = RTRIM$(st$)
  1218.  
  1219.  
  1220.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1221.  
  1222.     Subroutine: UPcase(st$)
  1223.     Subroutine: LOcase(st$)
  1224.     object file: case.obj
  1225.  
  1226.         Converts each character in st$ to Upper case / Lower case.
  1227.  
  1228.     Example:
  1229.          st$ = "This is a string of characters"
  1230.          CALL UPcase(st$)
  1231.          REM now st$ = "THIS IS A STRING OF CHARACTERS"
  1232.